<?php

namespace business\elasticsearch\services;


use business\elasticsearch\models\BigDataWinBidModel;

class BigDataWinBidService
{
    public function getDataList(
        $keyword,
        $province,
        $city,
        $companyType,
        $sourceType,
        $subSource,
        $publishDateLower,
        $publishDateUpper,
        $bidPriceLower,
        $bidPriceUpper,
        $areaCodes,
        $tags,
        $page,
        $pageSize
    )
    {
        $condition = $this->constructCondition(
            $keyword,
            $province,
            $city,
            $companyType,
            $sourceType,
            $subSource,
            $publishDateLower,
            $publishDateUpper,
            $bidPriceLower,
            $bidPriceUpper,
            $areaCodes,
            $tags
        );
        //var_dump(json_encode($condition));
        $query = BigDataWinBidModel::find()
            ->query($condition);

        //高亮处理
        $highlight = [
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields" => [
                "title" => new \stdClass(),
                "company_name" => new \stdClass(),
                "first_winbid_supplier_name" => new \stdClass(),
                "second_winbid_supplier_name" => new \stdClass(),
                "third_winbid_supplier_name" => new \stdClass(),
            ]
        ];
        $query->highlight($highlight);
        $query->orderBy(['publish_time' => SORT_DESC]);

        $total = $query->count();
        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $data = $query->asArray()->all();
        //数据处理
        $result = ['total' => $total, 'list' => []];
        foreach ($data as $dv) {
            $tmp = $dv['_source'];
            $tmp['nameSuggest'] = $tmp['title'];
            if (!empty($dv['highlight'])) {
                foreach ($dv['highlight'] as $key => $value) {
                    $tmp[$key . 'HL'] = isset($value[0]) ? $value[0] : '';
                }
            }
            $tmp = $this->formatWinbid($tmp);//定义输出字段
            $result['list'][] = $tmp;
        }
        return $result;
    }

    private function constructCondition(
        $keyword = '',
        $province = [],
        $city = [],
        $companyType = '',
        $sourceType = '',
        $subSource = '',
        $publishDateLower = '',
        $publishDateUpper = '',
        $bidPriceLower = '',
        $bidPriceUpper = '',
        $areaCodes = [],
        $tags = []
    )
    {
        $query = [];
        $slop = !empty(\Yii::$app->params['CommonDataDeveloperSlop']) ? \Yii::$app->params['CommonDataDeveloperSlop'] : 2;
        $must = [];
        $query['function_score']['query']['bool']['must'] = &$must;


        if (!empty($keyword)) {
            $should = [];
            $must[] = ['bool' => ['should' => &$should]];

            $titleBool = [];
            $titleBool[] = [
                'match_phrase' => ['title' => ["query" => $keyword, 'slop' => $slop]]
            ];
            $should[] = ["bool" => ["must" => $titleBool]];

            $companyBool = [];
            $companyBool[] = [
                'match_phrase' => ['company_name' => ["query" => $keyword, "boost" => 3, 'slop' => $slop]]
            ];
            $should[] = ["bool" => ["must" => $companyBool]];

            $supplier1Bool = [];
            $supplier1Bool[] = [
                'match_phrase' => ['first_winbid_supplier_name' => ["query" => $keyword, "boost" => 3, 'slop' => $slop]]
            ];
            $should[] = ["bool" => ["must" => $supplier1Bool]];

            $supplier2Bool = [];
            $supplier2Bool[] = [
                'match_phrase' => ['second_winbid_supplier_name' => ["query" => $keyword, "boost" => 3, 'slop' => $slop]]
            ];
            $should[] = ["bool" => ["must" => $supplier2Bool]];

            $supplier3Bool = [];
            $supplier3Bool[] = [
                'match_phrase' => ['third_winbid_supplier_name' => ["query" => $keyword, "boost" => 3, 'slop' => $slop]]
            ];
            $should[] = ["bool" => ["must" => $supplier3Bool]];
        }

        // 省
        if (!empty($province)) {
            $must[] = ["terms" => ['province_code' => $province]];
        }
        // 市
        if (!empty($city)) {
            $must[] = ["terms" => ['city_code' => $city]];
        }
        //混合省市，满足任意一个即可
        if (!empty($areaCodes)) {
            $shouldArea = [];
            $shouldArea[] = ["terms" => ['province_code' => $areaCodes]];
            $shouldArea[] = ["terms" => ['city_code' => $areaCodes]];
            $must[] = ['bool' => ['should' => $shouldArea]];
        }

        //企业类型
        if (!empty($companyType)) {
            $must[] = ["term" => ['company_type_label' => $companyType]];
        }

        //消息类型
        if (!empty($sourceType)) {
            $must[] = ["term" => ['type' => $sourceType]];
        }

        //消息类型
        if (!empty($subSource)) {
            $must[] = ["term" => ['source_sub' => $subSource]];
        }

        // 拿地面积
        $publishDateRange = [];
        if (!empty($publishDateLower)) {
            $publishDateRange['gte'] = date('Y-m-d', strtotime($publishDateLower));
        }
        if (!empty($publishDateUpper)) {
            $publishDateRange['lt'] = date('Y-m-d', strtotime($publishDateUpper));
        }
        if (!empty($publishDateRange)) {
            $must[] = ['range' => ['publish_time' => $publishDateRange]];
        }

        // 单价区间
        $priceRange = [];
        if (!empty($bidPriceLower)) {
            $priceRange['gte'] = $bidPriceLower;
        }
        if (!empty($bidPriceUpper)) {
            $priceRange['lt'] = $bidPriceUpper;
        }
        if (!empty($priceRange)) {
            $must[] = ['range' => ['first_winbid_price' => $priceRange]];
        }

        //标签
        if (!empty($tags)) {
            $tagShould = [];
            foreach ($tags as $k => $v) {
                if (!empty($v)) {
                    $tagShould[] = ['term' => [$k => $v]];
                }
            }
            $must[] = [
                'bool' => ['should' => $tagShould]
            ];
        }

        return $query;
    }


    public function guessNames($keyword, $pageSize)
    {
        $page = 1;
        $query = [];
        if (!empty($keyword)) {
            $query['function_score']['query']['bool']['must'][] = [
                'match_phrase' => ['title' => $keyword]
            ];
        }

        $query = BigDataWinBidModel::find()
            ->query($query);

        //高亮处理
        $highlight = [
            'pre_tags' => ['<em class="_high">'],
            'post_tags' => ['</em>'],
            "fields" => [
                "title" => new \stdClass(),
            ]
        ];
        $query->highlight($highlight);
        $query->orderBy(['_score' => SORT_DESC]);

        //分页处理
        $query->offset(($page - 1) * $pageSize)->limit($pageSize);
        $data = $query->asArray()->all();
        //数据处理
        $result = [];
        foreach ($data as $dv) {
            $item = array();
            $tmp = $dv['_source'];
            $tmp['nameSuggest'] = $tmp['title'];
            if (!empty($dv['highlight'])) {
                foreach ($dv['highlight'] as $key => $value) {
                    $tmp[$key . 'HL'] = isset($value[0]) ? $value[0] : '';
                }
            }
            $item['title'] = $tmp['title'];
            $item['titleHL'] = $tmp['titleHL'];
            $result[] = $item;
        }
        return $result;
    }

    public function formatWinbid($data)
    {
        //1、显示赋值：因为 es 的值如果为 null 会没有字段
        $return_params = [
            'pulsar_time' => 'string',
            'id' => 'string',
            'title' => 'string',
            'organizing_code' => 'string',
            'source' => 'string',
            'source_sub' => 'string',
            'publish_time' => 'string',
            'type' => 'string',
            'company_name' => 'string',
            'first_winbid_price' => 'string',
            'first_winbid_supplier_name' => 'string',
            'first_winbid_supplier_organizing_code' => 'string',
            'second_winbid_supplier_name' => 'string',
            'second_winbid_supplier_organizing_code' => 'string',
            'third_winbid_supplier_name' => 'string',
            'third_winbid_supplier_organizing_code' => 'string',
            'province' => 'string',
            'province_code' => 'string',
            'company_type_label' => 'string',
            'city' => 'string',
            'website_name' => 'string',
            'content_id' => 'string',
            'developer_top_100_label' => 'string',
            'new_decorate_expand_label' => 'string',
            'new_land_usage_expand_label' => 'string',
            'new_area_expand_label' => 'string',
            'price_gt_avg_label' => 'string',
        ];

        foreach ($return_params as $rk => $rv) {
            $tmp = isset($data[$rk]) ? $data[$rk] : '';
            $tmp = $tmp === '1990-01-01 00:00:00' ? '' : $tmp;
            if ($rv == 'int') {
                $data[$rk] = (int)$tmp;
            } elseif ($rv == 'array') {
                $data[$rk] = empty($tmp) ? [] : $tmp;
            } else {
                $data[$rk] = $tmp;
            }

        }

        return $data;
    }
}
